home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / gfx / show / mpeg_player122.lha / amiga / amiga.c next >
C/C++ Source or Header  |  1992-12-11  |  12KB  |  626 lines

  1. /*
  2.  * Implementation of the needed X functions for the
  3.  * Commodore Amiga
  4.  *
  5.  * Michael Balzer, December 1992
  6.  * balzer@heike.informatik.uni-dortmund.de
  7.  * m.balzer@aworld.(zer|sub.org|aworld.de)
  8.  *
  9.  * Release 1.0 (8.12.92):
  10.  *        First release, needs os3.0, can only display on
  11.  *        workbench or on 8 bit lores screen.
  12.  *
  13.  * Release 1.1 (11.12.92):
  14.  *        Now also runs on system 2.x. Uses reqtools.library
  15.  *        to ask the user for the screenmode. No HAM support yet.
  16.  *        Version string: 1.22 means Amiga version 2 of mpeg_play 1.2
  17.  *
  18.  * TODO:
  19.  *    - enhance color allocation for 2.x (error += usecount?)
  20.  *    - implement mono style dithering
  21.  *    - implement HAM mode
  22.  */
  23.  
  24.  
  25. #include <exec/types.h>
  26. #include <exec/memory.h>
  27. #include <exec/libraries.h>
  28. #include <intuition/intuition.h>
  29. #include <intuition/classes.h>
  30. #include <graphics/gfxbase.h>
  31. #include <graphics/modeid.h>
  32. #include <graphics/scale.h>
  33. #include <graphics/graphint.h>
  34. #include <dos/dos.h>
  35.  
  36. #include <clib/exec_protos.h>
  37. #include <clib/intuition_protos.h>
  38. #include <clib/graphics_protos.h>
  39. #include <clib/alib_protos.h>
  40.  
  41. #include <libraries/reqtools.h>
  42. #include <proto/reqtools.h>
  43. #define static
  44. #define __inline
  45. #include <inline/minreqtools.h>
  46.  
  47. #include <X11/Xlib.h>
  48. #include <X11/Xutil.h>
  49.  
  50. #include <stdio.h>
  51. #include <stdlib.h>
  52.  
  53. #define ABS(a) (((int)(a)<0) ? -(a) : (a))
  54.  
  55.  
  56. char *_version_ = "\0$VER: mpeg_play 1.22 (" __DATE__ ")";
  57.  
  58.  
  59. /***********************************************************/
  60.  
  61.  
  62. extern
  63. struct Library        *SysBase;
  64.  
  65. struct IntuitionBase *IntuitionBase = NULL;
  66. struct GfxBase        *GfxBase = NULL;
  67. struct ReqToolsBase    *ReqToolsBase = NULL;
  68.  
  69. struct Screen        *mpeg_screen = NULL;
  70. struct Window        *mpeg_window = NULL;
  71. struct RastPort        *rp = NULL;
  72.  
  73. struct RastPort        *temprp = NULL;
  74. struct BitMap        *tempbm = NULL;
  75. struct ViewPort        *vp = NULL;
  76.  
  77. char                *amiga_option = NULL;
  78.  
  79. int                    offx, offy;
  80.  
  81. struct ColorMap        *cm = NULL;
  82. int                    used_colors[ 256 ];
  83. int                    used_cnt = 0;
  84.  
  85. UWORD                saved_colors[ 256 ];
  86. int                    saved_cnt = 0;
  87.  
  88. int                    rev3;
  89.  
  90.  
  91. /***********************************************************/
  92.  
  93. /* support routines for os revision 2 */
  94.  
  95. struct BitMap *myAllocBitMap( unsigned long sizex, unsigned long sizey,
  96.     unsigned long depth, unsigned long flags,
  97.     struct BitMap *friend_bitmap )
  98. {
  99.     struct BitMap *bm;
  100.     
  101.     bm = AllocVec( sizeof *bm, MEMF_CLEAR );
  102.     
  103.     if( bm )
  104.     {
  105.         int i;
  106.         
  107.         bm->BytesPerRow = (sizex + 15) >> 3 & 0xfffe;
  108.         bm->Rows = sizey;
  109.         bm->Depth = depth;
  110.         
  111.         for( i=0; i<depth; i++ )
  112.         {
  113.             if( !(bm->Planes[i] = AllocRaster(sizex, sizey)) )
  114.             {
  115.                 while( i-- ) FreeRaster( bm->Planes[i], sizex, sizey );
  116.                 FreeVec( bm );
  117.                 bm = 0;
  118.                 break;
  119.             }
  120.         }
  121.     }
  122.     
  123.     return bm;
  124. }
  125.  
  126.  
  127. void myFreeBitMap( struct BitMap *bm )
  128. {
  129.     while( bm->Depth-- )
  130.         FreeRaster( bm->Planes[bm->Depth], bm->BytesPerRow*8, bm->Rows );
  131.     FreeVec( bm );
  132. }
  133.  
  134.  
  135. LONG myObtainBestPenA( struct ColorMap *cm, unsigned long r, unsigned long g,
  136.     unsigned long b, struct TagItem *tags )
  137. {
  138.     int i, best, err, besterr;
  139.     int br, bg, bb;
  140.     int colors;
  141.     
  142.     /* Farbwerte auf 4 Bit bringen */
  143.     
  144.     r >>= 28; g >>= 28; b >>= 28;
  145.     
  146.     /* Strategie: Zunächst die Farbe suchen, die der gewünschten
  147.      * am nächsten liegt. Wenn Farbe >= 4, Farbe auf Mittelwert zw.
  148.      * aktuellen und gesuchten Werten setzen und zurückgeben.
  149.      * Die unteren vier bleiben unverändert (Workbench).
  150.      */
  151.     
  152.     best = 0;
  153.     besterr = 100;
  154.     
  155.     colors = 1 << rp->BitMap->Depth;
  156.     
  157.     for( i=0; i<colors; i++ )
  158.     {
  159.         long rgb = GetRGB4( cm, i );
  160.         int cr, cg, cb;
  161.         
  162.         cr = rgb >> 8 & 15;
  163.         cg = rgb >> 4 & 15;
  164.         cb = rgb      & 15;
  165.         
  166.         err = ABS( r - cr )
  167.             + ABS( g - cg )
  168.             + ABS( b - cb );
  169.         
  170.         if( err < besterr )
  171.         {
  172.             best = i;
  173.             besterr = err;
  174.             br = cr;
  175.             bg = cg;
  176.             bb = cb;
  177.         }
  178.     }
  179.     
  180.     if( best >= 4 && besterr != 0 )
  181.     {
  182.         /* Farbe anpassen */
  183.         SetRGB4( vp, best,
  184.             (r + br) / 2,
  185.             (g + bg) / 2,
  186.             (b + bb) / 2 );
  187.     }
  188.     
  189.     return best;
  190. }
  191.  
  192.  
  193. void myReleasePen( struct ColorMap *cm, unsigned long n )
  194. {
  195.     /* Farbe restaurieren */
  196.     long rgb = saved_colors[n];
  197.     int cr, cg, cb;
  198.     
  199.     cr = rgb >> 8 & 15;
  200.     cg = rgb >> 4 & 15;
  201.     cb = rgb      & 15;
  202.     
  203.     SetRGB4( vp, n, cr, cg, cb );
  204. }
  205.  
  206.  
  207. /***********************************************************/
  208.  
  209.  
  210. void amiga_closedown( void )
  211. {
  212.     if( cm )
  213.     {
  214.         while( used_cnt-- )
  215.             if( rev3 ) ReleasePen( cm, used_colors[used_cnt] );
  216.             else myReleasePen( cm, used_colors[used_cnt] );
  217.     }
  218.     
  219.     if( mpeg_window ) CloseWindow( mpeg_window );
  220.     if( mpeg_screen ) CloseScreen( mpeg_screen );
  221.     
  222.     if( tempbm )
  223.     {
  224.         if( rev3 ) FreeBitMap( tempbm );
  225.         else myFreeBitMap( tempbm );
  226.     }
  227.     if( temprp ) FreeVec( temprp );
  228.  
  229.     if( ReqToolsBase )    CloseLibrary( (struct Library *) ReqToolsBase );
  230.     if( IntuitionBase )    CloseLibrary( (struct Library *) IntuitionBase );
  231.     if( GfxBase )        CloseLibrary( (struct Library *) GfxBase );
  232. }
  233.  
  234.  
  235. Display *XOpenDisplay( _Xconst char *display_name )
  236. {
  237.     struct rtScreenModeRequester *scrmodereq;
  238.     int y;
  239.     
  240.     static struct TagItem windowtags[] =
  241.     {
  242.         {    WA_PubScreen,    NULL },
  243.         {    WA_Left,        32 },
  244.         {    WA_Top,            32 },
  245.         {    WA_Width,        160 },
  246.         {    WA_Height,        120 },
  247.         {    WA_Title,        (ULONG) "MPEG Window" },
  248.         {    WA_IDCMP,        IDCMP_CLOSEWINDOW },
  249.         {    WA_Flags,        WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_NOCAREREFRESH | WFLG_ACTIVATE | WFLG_RMBTRAP },
  250.         {    WA_ScreenTitle,    (ULONG) "MPEG Player V1.2, Amiga version by Michael Balzer 12/92" },
  251.         {    TAG_END }
  252.     };
  253.     
  254.     if( !IntuitionBase )
  255.     {
  256.         /* install closedown routine */
  257.         
  258.         atexit( amiga_closedown );
  259.         
  260.         /* open shared libraries */
  261.         
  262.         IntuitionBase = (struct IntuitionBase *) OpenLibrary( "intuition.library", 0 );
  263.         if( !IntuitionBase ) exit(20);
  264.         
  265.         GfxBase = (struct GfxBase *) OpenLibrary( "graphics.library", 0 );
  266.         if( !GfxBase ) exit(20);
  267.         
  268.         ReqToolsBase = (struct ReqToolsBase *) OpenLibrary( "reqtools.library", 38 );
  269.         if( !ReqToolsBase )
  270.         {
  271.             puts( "I need reqtools.library v38!\n" );
  272.             exit(20);
  273.         }
  274.         
  275.         rev3 = (GfxBase->LibNode.lib_Version >= 39);
  276.         
  277.         /* open some display */
  278.         
  279.         if( strcmp(amiga_option, "window") == 0 )
  280.         {
  281.             /* try to open a window */
  282.             struct Screen *s;
  283.             
  284.             if( s = LockPubScreen(NULL) )
  285.             {
  286.                 windowtags[0].ti_Data = (ULONG) s;
  287.                 mpeg_window = OpenWindowTagList( NULL, windowtags );
  288.                 if( mpeg_window )
  289.                 {
  290.                     rp = mpeg_window->RPort;
  291.                     offx = mpeg_window->BorderLeft;
  292.                     offy = mpeg_window->BorderTop;
  293.                 }
  294.                 
  295.                 UnlockPubScreen( NULL, s );
  296.             }
  297.         }
  298.         
  299.         /* fallback to own screen */
  300.         
  301.         if( !mpeg_window )
  302.         {
  303.             if( scrmodereq = rtAllocRequestA( RT_SCREENMODEREQ, NULL ) )
  304.             {
  305.                 if( rtScreenModeRequest( scrmodereq, "MPEG: Pick a screen mode",
  306.                     RTSC_Flags, SCREQF_DEPTHGAD|SCREQF_SIZEGADS|SCREQF_AUTOSCROLLGAD|SCREQF_OVERSCANGAD,
  307.                     TAG_END ) )
  308.                 {
  309.                     mpeg_screen = OpenScreenTags( NULL,
  310.                         SA_Title,        (ULONG) "MPEG Screen",
  311.                         SA_DisplayID,    scrmodereq->DisplayID,
  312.                         SA_Width,        scrmodereq->DisplayWidth,
  313.                         SA_Height,        scrmodereq->DisplayHeight,
  314.                         SA_Depth,        scrmodereq->DisplayDepth,
  315.                         SA_Overscan,    scrmodereq->OverscanType,
  316.                         SA_AutoScroll,    scrmodereq->AutoScroll,
  317.                         SA_Quiet,        TRUE,
  318.                         SA_Interleaved,    TRUE,
  319.                         SA_SharePens,    TRUE,
  320.                         TAG_END );
  321.                     
  322.                     /* Autoscroll would need a backdrop window, but that
  323.                      * would posssibly slow it down even more...
  324.                      */
  325.                 }
  326.                 
  327.                 rtFreeRequest( scrmodereq );
  328.  
  329.                 if( !mpeg_screen )
  330.                     exit(20);
  331.                 
  332.                 rp = &mpeg_screen->RastPort;
  333.                 offx = offy = 0;
  334.             }
  335.             else
  336.             {
  337.                 puts( "Out of memory!" );
  338.                 exit(0);
  339.             }
  340.         }
  341.         
  342.         /* Viewport und Colormap bestimmen */
  343.         
  344.         vp = (mpeg_screen)
  345.             ? &mpeg_screen->ViewPort
  346.             : &mpeg_window->WScreen->ViewPort;
  347.  
  348.         cm = vp -> ColorMap;
  349.  
  350.         /* Farben sichern */
  351.         
  352.         saved_cnt = 1 << rp->BitMap->Depth;
  353.         for( y=0; y<saved_cnt; y++ )
  354.             saved_colors[y] = GetRGB4( cm, y );
  355.         
  356.         /* temporären Rastport aufsetzen */
  357.         
  358.         temprp = AllocVec( sizeof *temprp, MEMF_ANY );
  359.         memcpy( temprp, rp, sizeof *temprp );
  360.         temprp->Layer = 0;
  361.         
  362.         if( rev3 )
  363.             tempbm = AllocBitMap( rp->BitMap->BytesPerRow * 8, 1,
  364.                 rp->BitMap->Depth, NULL, rp->BitMap );
  365.         else
  366.             tempbm = myAllocBitMap( rp->BitMap->BytesPerRow * 8, 1,
  367.                 rp->BitMap->Depth, NULL, rp->BitMap );
  368.         
  369.         temprp->BitMap = tempbm;
  370.     }
  371.     
  372.     return (Display *) 1;
  373. }
  374.  
  375.  
  376. int XDefaultScreen( Display *display )
  377. {
  378.     return 1;
  379. }
  380.  
  381.  
  382. XFlush( Display *display )
  383. {
  384. }
  385.  
  386.  
  387. /***************************************************************/
  388.  
  389.  
  390. Window XRootWindow(
  391.     Display*        display,
  392.     int                screen_number )
  393. {
  394.     return 1;
  395. }
  396.  
  397.  
  398. Window XCreateSimpleWindow(
  399.     Display*        display,
  400.     Window            parent,
  401.     int                x,
  402.     int                y,
  403.     unsigned int    width,
  404.     unsigned int    height,
  405.     unsigned int    border_width,
  406.     unsigned long    border,
  407.     unsigned long    background )
  408. {
  409.     return 1;
  410. }
  411.  
  412.  
  413. Window XCreateWindow(
  414.     Display*        display,
  415.     Window            parent,
  416.     int                x,
  417.     int                y,
  418.     unsigned int    width,
  419.     unsigned int    height,
  420.     unsigned int    border_width,
  421.     int                depth,
  422.     unsigned int    class,
  423.     Visual*            visual,
  424.     unsigned long    valuemask,
  425.     XSetWindowAttributes*    attributes )
  426. {
  427.     /* Generiert Fenster auf Full-Color-Display */
  428.     /* (HAM Support?) */
  429.     return 0;
  430. }
  431.  
  432.  
  433. XSetStandardProperties(
  434.     Display*        display,
  435.     Window            w,
  436.     _Xconst char*    window_name,
  437.     _Xconst char*    icon_name,
  438.     Pixmap            icon_pixmap,
  439.     char**            argv,
  440.     int                argc,
  441.     XSizeHints*        hints )
  442. {
  443. }
  444.  
  445.  
  446. XMapWindow(
  447.     Display*        display,
  448.     Window            w )
  449. {
  450. }
  451.  
  452.  
  453. XResizeWindow(
  454.     Display*        display,
  455.     Window            w,
  456.     unsigned int    width,
  457.     unsigned int    height )
  458. {
  459.     if( mpeg_screen ) return;
  460.     
  461.     ChangeWindowBox( mpeg_window,
  462.         mpeg_window->LeftEdge, mpeg_window->TopEdge,
  463.         width + mpeg_window->BorderLeft + mpeg_window->BorderRight,
  464.         height + mpeg_window->BorderTop + mpeg_window->BorderBottom
  465.     );
  466. }
  467.  
  468.  
  469. /***************************************************************/
  470.  
  471.  
  472. Status XMatchVisualInfo(
  473.     Display*        display,
  474.     int                screen,
  475.     int                depth,
  476.     int                class,
  477.     XVisualInfo*    vinfo_return )
  478. {
  479.     return( depth <= 8 );
  480. }
  481.  
  482.  
  483. XVisualInfo *XGetVisualInfo(
  484.     Display*        display,
  485.     long            vinfo_mask,
  486.     XVisualInfo*    vinfo_template,
  487.     int*            nitems_return )
  488. {
  489.     *nitems_return = 0;
  490.     return vinfo_template;
  491. }
  492.  
  493.  
  494. GC XCreateGC(
  495.     Display*        display,
  496.     Drawable        d,
  497.     unsigned long    valuemask,
  498.     XGCValues*        values )
  499. {
  500.     return (GC) 1;
  501. }
  502.  
  503.  
  504. /***************************************************************/
  505.  
  506.  
  507. XImage *XCreateImage(
  508.     Display*        display,
  509.     Visual*            visual,
  510.     unsigned int    depth,
  511.     int                format,
  512.     int                offset,
  513.     char*            data,
  514.     unsigned int    width,
  515.     unsigned int    height,
  516.     int                bitmap_pad,
  517.     int                bytes_per_line )
  518. {
  519.     XImage *xi;
  520.     
  521.     if( xi = calloc(sizeof *xi, 1) )
  522.     {
  523.         xi->width   = width;
  524.         xi->height  = height;
  525.         xi->depth   = depth;
  526.         
  527.         xi->f.destroy_image = (int (*)()) free;
  528.     }
  529.     
  530.     return xi;
  531. }
  532.  
  533.  
  534. XPutImage(
  535.     Display*        display,
  536.     Drawable        d,
  537.     GC                gc,
  538.     XImage*            image,
  539.     int                src_x,
  540.     int                src_y,
  541.     int                dest_x,
  542.     int                dest_y,
  543.     unsigned int    width,
  544.     unsigned int    height       )
  545. {
  546.     struct IntuiMessage    *imsg;
  547.     ULONG                class;
  548.  
  549.     /* in image->data ist das Bild als Folge von Bytes,
  550.      * display zeigt auf nix,
  551.      * d und gc sind egal,
  552.      * src_? und dest_? sind hier immer 0,
  553.      * width und height stimmen mit den Bilddimensionen überein
  554.      * (oder sollten zumindest...)
  555.      */
  556.     
  557.     WritePixelArray8( rp, offx, offy, offx+width-1, offy+height-9, image->data, temprp );
  558.     /* y-Height - 9 because of 8 lines of random pixels beyond the pic */
  559.     
  560.     if( mpeg_window )
  561.     {
  562.         while( imsg = (struct IntuiMessage *) GetMsg(mpeg_window->UserPort) )
  563.         {
  564.             class = imsg->Class;
  565.             ReplyMsg( (struct Message *) imsg );
  566.             
  567.             if( class == CLOSEWINDOW )
  568.                 exit( 0 );
  569.         }
  570.     }
  571. }
  572.  
  573.  
  574. /***************************************************************/
  575.  
  576.  
  577. Colormap XCreateColormap(
  578.     Display*        display,
  579.     Window            w,
  580.     Visual*            visual,
  581.     int                alloc )
  582. {
  583.     return 1;
  584. }
  585.  
  586.  
  587. Colormap XDefaultColormap(
  588.     Display*        display,
  589.     int                screen_number )
  590. {
  591.     return 1;
  592. }
  593.  
  594.  
  595. Status XAllocColor(
  596.     Display*        display,
  597.     Colormap        colormap,
  598.     XColor*            xcolor )
  599. {
  600.     long color;
  601.     
  602.     if( rev3 )
  603.         color = ObtainBestPenA( cm,
  604.             xcolor->red << 16, xcolor->green << 16, xcolor->blue << 16,
  605.             NULL );
  606.     else
  607.         color = myObtainBestPenA( cm,
  608.             xcolor->red << 16, xcolor->green << 16, xcolor->blue << 16,
  609.             NULL );
  610.     
  611.     used_colors[ used_cnt++ ] = color;
  612.     xcolor->pixel = color;
  613.     
  614.     return color;
  615. }
  616.  
  617.  
  618. /***************************************************************/
  619.  
  620.  
  621. XFree( void *data )
  622. {
  623. }
  624.  
  625.  
  626.